#include "Player.h"
#include "Game.h"
#include "Projectile.h"

Player::Player() : Entity()
{
    images[STANDING] = new Image("images/player/standing.bmp", COL_KEY);
    images[JUMPING] = new Image("images/player/jumping.bmp", COL_KEY);
    images[FALLING] = new Image("images/player/falling.bmp", COL_KEY);
    images[WALKING] = new Animation("images/player/walking.bmp", 4, 100, COL_KEY);
    images[KICKING] = images[JUMP_KICKING] = new Animation("images/player/kicking.bmp", 3, 100, COL_KEY);
    images[PUNCHING] = images[JUMP_PUNCHING] = new Animation("images/player/punching.bmp", 3, 50, COL_KEY);

    images[CROUCHING] = new Image("images/player/crouching.bmp", COL_KEY);
    images[CROUCH_PUNCHING] = new Animation("images/player/crouch-punching.bmp", 3, 100, COL_KEY);
    images[CROUCH_KICKING] = new Animation("images/player/crouch-kicking.bmp", 3, 150, COL_KEY);

	images[DEAD] = new Image("images/player/dead.bmp", COL_KEY);
	images[RECOILING] = new Image("images/player/recoiling.bmp", COL_KEY);

    ((Animation*) images[PUNCHING])->setLooping(false);
    ((Animation*) images[JUMP_PUNCHING])->setLooping(false);
    ((Animation*) images[CROUCH_PUNCHING])->setLooping(false);
    ((Animation*) images[KICKING])->setLooping(false);
    ((Animation*) images[JUMP_KICKING])->setLooping(false);
    ((Animation*) images[CROUCH_KICKING])->setLooping(false);

	//projectileImage = new Image("images/knife.bmp", COL_KEY);
	projectileImage = new Animation("images/ninjastar.bmp", 2, 100, COL_KEY);
	projectileImage->setRefBottomCentre();

	health = PLAYER_MAX_HEALTH;
    x = 160;
    y = 0;

	score = 0;

    state = STANDING;

    for(int i=0; i< NUM_PLAYER_STATES; i++)
    {
        if(images[i] == NULL){
            printf("Warning: Player has no animation for state number %d\n", i);
        }else{
			images[i]->setRefBottomCentre();
        }
    }

	images[DEAD]->setRefCentre();
}

Player::~Player()
{
	delete projectileImage;

	for(int i=0; i<NUM_PLAYER_STATES; i++)
	{
		// Don't delete duplicate images
		if(i == JUMP_KICKING || i == JUMP_PUNCHING) break;

		if( images[i] != NULL ) delete images[i];
	}
}

Image* Player::getCurrentImage()
{
    return images[state];
}

void Player::jump()
{
	v = PLAYER_JUMP_VELOCITY;
}

void Player::shakeGrabbers()
{
	//TODO: Find a better way of doing this
	list<Entity*> grabbingEnemies = this->grabbingEnemies;

	for(list<Entity*>::iterator i = grabbingEnemies.begin(); i != grabbingEnemies.end(); i++ )
	{
		(*i)->damage(PLAYER_SHAKE_DAMAGE, this, false);
	}
}

void Player::tick(){
	if(!alive){
		state = DEAD;
		return;
	}

	if(u != 0.0f){
		state = RECOILING;
		return;
	}

	if( ! grabbingEnemies.empty() )
	{
		state = STANDING;

		if(flipped)
		{
			if( Keyboard::isKeyPressed(SDLK_RIGHT) ){
				flipped = false;
				shakeGrabbers();
			}
		}
		else
		{
			if( Keyboard::isKeyPressed(SDLK_LEFT) ){
				flipped = true;
				shakeGrabbers();
			}
		}

		return;
	}

    if(state == PUNCHING || state == KICKING || state == CROUCH_KICKING || state == CROUCH_PUNCHING || state == JUMP_PUNCHING || state == JUMP_KICKING)
    {
		list<Entity*>* entities = Game::getInstance()->getEntities();

		for(list<Entity*>::iterator i = entities->begin(); i != entities->end(); i++)
		{
			Entity* e = *i;

			if(e != this && e->isAlive() && collidesWith(e))
			{
				e->damage(PLAYER_ATTACK_DAMAGE, this);
			}
		}

		if(state != JUMP_PUNCHING && state != JUMP_KICKING)
		{
			if(((Animation*) images[state])->getPlayCount() < 1)
			{
				return;
			}
			else if(state == PUNCHING || state == CROUCH_PUNCHING){
				Game::getInstance()->addEntity(
					new Projectile(this, projectileImage, x, crouching ? y+13 : y+25, flipped ? -7.0f : 7.0f, 0.0f, PLAYER_PROJECTILE_DAMAGE, false)
				);
			}
		}
    }

    attacking = (state == JUMP_KICKING || state == JUMP_PUNCHING);

    if(touchingGround)
    {
        if(state == JUMP_PUNCHING || state == JUMP_KICKING) attacking = false;
        state = STANDING;
        crouching = false;

        if(Keyboard::isKeyPressed(SDLK_DOWN))
        {
            crouching = true;
            state = CROUCHING;
        }
    }
    else
    {
        if(state != JUMP_KICKING && state != JUMP_PUNCHING)
        {
            if(v > 0) state = JUMPING; else state = FALLING;
        }
    }

    if(Keyboard::isKeyPressed(SDLK_LEFT)){
		flipped = true;

		if(!crouching){
			moveLeft();
			if(touchingGround) state = WALKING;
		}
    }

    if(Keyboard::isKeyPressed(SDLK_RIGHT)){
		flipped = false;

		if(!crouching){
			moveRight();
			if(touchingGround) state = WALKING;
		}
    }

    if(attacking) return;

    // Kicking
    if(Keyboard::isKeyPressed(SDLK_LCTRL))
    {
        state = KICKING;
        if(crouching) state = CROUCH_KICKING;
        if(!touchingGround) state = JUMP_KICKING;

        ((Animation*) images[state])->start();

        attacking = true;
        return;
    }

    // Punching
    if(Keyboard::isKeyPressed(SDLK_LALT))
    {
        state = PUNCHING;
        if(crouching) state = CROUCH_PUNCHING;
        if(!touchingGround) state = JUMP_PUNCHING;

        ((Animation*) images[state])->start();

        attacking = true;
        return;
    }

    if(Keyboard::isKeyPressed(SDLK_SPACE) && touchingGround){
        jump();
        state = JUMPING;

        crouching = false; // Just in case
        attacking = false;
    }
}
